#include "selfinfowidget.h"
#include "debug.h"
#include "model/data.h"
#include "model/datacenter.h"
#include "toast.h"

SelfInfoWidget::SelfInfoWidget(QWidget *parent) : QDialog(parent)
{
    // 1. 设置整个窗口的属性
    this->setFixedSize(500, 250);
    this->setWindowTitle("个人信息");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    // 窗口被关闭时自动销毁该对话框
    this->setAttribute(Qt::WA_DeleteOnClose);
    // 把窗口移动到鼠标当前的位置
    this->move(QCursor::pos());

    // 2.创建布局管理器
    _layout = new QGridLayout();
    _layout->setHorizontalSpacing(10);
    _layout->setVerticalSpacing(3);
    _layout->setContentsMargins(20, 20, 20, 0);
    _layout->setAlignment(Qt::AlignTop);
    this->setLayout(_layout);

    // 3. 创建头像
    _avatarBtn = new QPushButton();
    _avatarBtn->setFixedSize(75, 75);
    _avatarBtn->setIconSize(QSize(75, 75));
    _avatarBtn->setStyleSheet("QPushButton { border: none; background-color: transparent; }");
    _layout->addWidget(_avatarBtn, 0, 0, 3, 1);

    QString labelStyle = "QLabel { font-size: 14px; font-weight: 800; }";
    QString btnStyle   = "QPushButton { border: none; background-color: transparent; }";
    btnStyle += "QPushButton:pressed { background-color: rgb(210, 210, 210); }";
    QString editStyle = "QLineEdit { border: none; border-radius:5px; padding-left:2px; }";

    int height = 30;

    // 4. 添加用户的 id 显示
    _idTag = new QLabel();
    _idTag->setFixedSize(50, height);
    _idTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    _idTag->setText("序号");
    _idTag->setStyleSheet(labelStyle);

    _idLabel = new QLabel();
    _idLabel->setFixedHeight(height);
    _idLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 5. 添加用户的名字显示
    _nameTag = new QLabel();
    _nameTag->setFixedSize(50, height);
    _nameTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    _nameTag->setText("昵称");
    _nameTag->setStyleSheet(labelStyle);

    _nameLabel = new QLabel();
    _nameLabel->setFixedHeight(height);
    _nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    _nameModifyBtn = new QPushButton();
    _nameModifyBtn->setFixedSize(70, 25);
    _nameModifyBtn->setIconSize(QSize(20, 20));
    _nameModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    _nameModifyBtn->setStyleSheet(btnStyle);

    _nameEdit = new QLineEdit();
    _nameEdit->setFixedHeight(height);
    _nameEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    _nameEdit->setStyleSheet(editStyle);
    _nameEdit->hide();

    _nameSubmitbtn = new QPushButton();
    _nameSubmitbtn->setFixedSize(70, 25);
    _nameSubmitbtn->setIconSize(QSize(20, 20));
    _nameSubmitbtn->setIcon(QIcon(":/resource/image/submit.png"));
    _nameSubmitbtn->setStyleSheet(btnStyle);
    _nameSubmitbtn->hide();

    // 6. 添加个性签名
    _descTag = new QLabel();
    _descTag->setFixedSize(50, height);
    _descTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    _descTag->setText("签名");
    _descTag->setStyleSheet(labelStyle);

    _descLabel = new QLabel();
    _descLabel->setFixedHeight(height);
    _descLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    _descModifyBtn = new QPushButton();
    _descModifyBtn->setFixedSize(70, 25);
    _descModifyBtn->setIconSize(QSize(20, 20));
    _descModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    _descModifyBtn->setStyleSheet(btnStyle);

    _descEdit = new QLineEdit();
    _descEdit->setFixedHeight(height);
    _descEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    _descEdit->setStyleSheet(editStyle);
    _descEdit->hide();

    _descSubmitbtn = new QPushButton();
    _descSubmitbtn->setFixedSize(70, 25);
    _descSubmitbtn->setIconSize(QSize(20, 20));
    _descSubmitbtn->setIcon(QIcon(":/resource/image/submit.png"));
    _descSubmitbtn->setStyleSheet(btnStyle);
    _descSubmitbtn->hide();

    // 7. 添加电话
    _phoneTag = new QLabel();
    _phoneTag->setFixedSize(50, height);
    _phoneTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    _phoneTag->setText("电话");
    _phoneTag->setStyleSheet(labelStyle);

    _phoneLabel = new QLabel();
    _phoneLabel->setFixedHeight(height);
    _phoneLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    _phoneModifyBtn = new QPushButton();
    _phoneModifyBtn->setFixedSize(70, 25);
    _phoneModifyBtn->setIconSize(QSize(20, 20));
    _phoneModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    _phoneModifyBtn->setStyleSheet(btnStyle);

    _phoneEdit = new QLineEdit();
    _phoneEdit->setFixedHeight(height);
    _phoneEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    _phoneEdit->setStyleSheet(editStyle);
    _phoneEdit->hide();

    _phoneSubmitBtn = new QPushButton();
    _phoneSubmitBtn->setFixedSize(70, 25);
    _phoneSubmitBtn->setIconSize(QSize(20, 20));
    _phoneSubmitBtn->setIcon(QIcon(":/resource/image/submit.png"));
    _phoneSubmitBtn->setStyleSheet(btnStyle);
    _phoneSubmitBtn->hide();

    // 8. 添加验证码
    _verifyCodeTag = new QLabel();
    _verifyCodeTag->setFixedSize(50, height);
    _verifyCodeTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    _verifyCodeTag->setText("验证码");
    _verifyCodeTag->setStyleSheet(labelStyle);

    _verifyCodeEdit = new QLineEdit();
    _verifyCodeEdit->setFixedHeight(height);
    _verifyCodeEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    _verifyCodeEdit->setStyleSheet(editStyle);
    _verifyCodeEdit->hide();

    _getVerifyCodeBtn = new QPushButton();
    _getVerifyCodeBtn->setText("获取验证码");
    _getVerifyCodeBtn->setStyleSheet(
        "QPushButton { border: none; background-color: transparent; } QPushButton:pressed { "
        "background-color: rgb(231, 231, 231); }");
    _getVerifyCodeBtn->setFixedSize(70, height);
    _getVerifyCodeBtn->hide();

    // 9. 添加到布局管理器
    // 第 0 列被头像占用，下列内容从第一列往后排
    _layout->addWidget(_idTag, 0, 1);
    _layout->addWidget(_idLabel, 0, 2);

    _layout->addWidget(_nameTag, 1, 1);
    _layout->addWidget(_nameLabel, 1, 2);
    _layout->addWidget(_nameModifyBtn, 1, 3);

    _layout->addWidget(_descTag, 2, 1);
    _layout->addWidget(_descLabel, 2, 2);
    _layout->addWidget(_descModifyBtn, 2, 3);

    _layout->addWidget(_phoneTag, 3, 1);
    _layout->addWidget(_phoneLabel, 3, 2);
    _layout->addWidget(_phoneModifyBtn, 3, 3);

#if TEST_UI
    _idLabel->setText("1234");
    _nameLabel->setText("张三");
    _descLabel->setText("从今天开始认真敲代码");
    _phoneLabel->setText("12345678901");
    _avatarBtn->setIcon(QIcon(":/resource/image/defaultAvatar.png"));
#endif

    // 10. 连接信号槽
    initSignalSlot();

    // 11. 加载数据到界面上
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    model::UserInfo *myself       = dataCenter->getMyself();
    if (myself != nullptr)
    {
        _avatarBtn->setIcon(myself->avatar);
        _idLabel->setText(myself->userId);
        _nameLabel->setText(myself->nickname);
        _descLabel->setText(myself->description);
        _phoneLabel->setText(myself->phone);
    }
}

void SelfInfoWidget::initSignalSlot()
{
    connect(_nameModifyBtn, &QPushButton::clicked, this,
            [=]()
            {
                // 把当前的 nameLabel 和 nameModifyBtn 隐藏起来
                _nameLabel->hide();
                _nameModifyBtn->hide();
                _layout->removeWidget(_nameLabel);
                _layout->removeWidget(_nameModifyBtn);
                // 把 nameEdit 和 nameSubmitBtn 显示出来
                _nameEdit->show();
                _nameSubmitbtn->show();
                _layout->addWidget(_nameEdit, 1, 2);
                _layout->addWidget(_nameSubmitbtn, 1, 3);
                // 把输入框的内容进行设置
                _nameEdit->setText(_nameLabel->text());
            });

    connect(_descModifyBtn, &QPushButton::clicked, this,
            [=]()
            {
                _descLabel->hide();
                _descModifyBtn->hide();
                _layout->removeWidget(_descLabel);
                _layout->removeWidget(_descModifyBtn);

                _descEdit->show();
                _descSubmitbtn->show();
                _layout->addWidget(_descEdit, 2, 2);
                _layout->addWidget(_descSubmitbtn, 2, 3);

                _descEdit->setText(_descLabel->text());
            });

    connect(_phoneModifyBtn, &QPushButton::clicked, this,
            [=]()
            {
                _phoneLabel->hide();
                _phoneModifyBtn->hide();
                _layout->removeWidget(_phoneLabel);
                _layout->removeWidget(_phoneModifyBtn);

                _phoneEdit->show();
                _phoneSubmitBtn->show();
                _layout->addWidget(_phoneEdit, 3, 2);
                _layout->addWidget(_phoneSubmitBtn, 3, 3);

                _verifyCodeTag->show();
                _verifyCodeEdit->show();
                _getVerifyCodeBtn->show();
                _layout->addWidget(_verifyCodeTag, 4, 1);
                _layout->addWidget(_verifyCodeEdit, 4, 2);
                _layout->addWidget(_getVerifyCodeBtn, 4, 3);

                _phoneEdit->setText(_phoneLabel->text());
            });

    connect(_nameSubmitbtn, &QPushButton::clicked, this, &SelfInfoWidget::clickNameSubmitBtn);
    connect(_descSubmitbtn, &QPushButton::clicked, this, &SelfInfoWidget::clickDescSubmitBtn);
    connect(_getVerifyCodeBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickGetVerifyCodeBtn);
    connect(_phoneSubmitBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickPhoneSubmitBtn);
    connect(_avatarBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickAvatarBtn);
}

void SelfInfoWidget::clickNameSubmitBtn()
{
    // 1. 从输入框中，拿到修改后的昵称
    const QString &nickname = _nameEdit->text();
    if (nickname.isEmpty())
    {
        return;
    }
    // 2. 发送网络请求
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::changeNicknameDone, this, &SelfInfoWidget::clickNameSubmitBtnDone,
            Qt::UniqueConnection);
    dataCenter->changeNicknameAsync(nickname);
}

void SelfInfoWidget::clickNameSubmitBtnDone()
{
    // 对界面控件进行切换，把输入框换回 label，把 提交按钮 换回 编辑按钮
    // 把输入框中的文本设置为 label 中的文本
    _layout->removeWidget(_nameEdit);
    _nameEdit->hide();
    _layout->addWidget(_nameLabel, 1, 2);
    _nameLabel->show();
    _nameLabel->setText(_nameEdit->text());

    _layout->removeWidget(_nameSubmitbtn);
    _nameSubmitbtn->hide();
    _layout->addWidget(_nameModifyBtn, 1, 3);
    _nameModifyBtn->show();
}

void SelfInfoWidget::clickDescSubmitBtn()
{
    // 1. 从输入框拿到输入的签名内容
    const QString &desc = _descEdit->text();
    if (desc.isEmpty())
    {
        return;
    }
    // 2. 发送网络请求
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::changeDescriptionDone, this, &SelfInfoWidget::clickDescSubmitBtnDone,
            Qt::UniqueConnection);
    dataCenter->changeDescriptionAsync(desc);
}

void SelfInfoWidget::clickDescSubmitBtnDone()
{
    // 切换界面
    //  把 label 替换回输入框，把 提交按钮 换回 编辑按钮
    _layout->removeWidget(_descEdit);
    _descEdit->hide();
    _layout->addWidget(_descLabel, 2, 2);
    _descLabel->show();
    _descLabel->setText(_descEdit->text());

    _layout->removeWidget(_descSubmitbtn);
    _descSubmitbtn->hide();
    _layout->addWidget(_descModifyBtn, 2, 3);
    _descModifyBtn->show();
}

void SelfInfoWidget::clickGetVerifyCodeBtn()
{
    // 1. 获取到输入框中的手机号
    const QString &phone = _phoneEdit->text();
    if (phone.isEmpty())
    {
        return;
    }

    // 2. 给服务器发起请求
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::getVerifyCodeDone, this,
            [=]() { Toast::showMessage("短信验证码已经发送"); });
    dataCenter->getVerifyCodeAsync(phone);

    // 3. 把发起请求的手机号码保存起来
    // 后续点击提交按钮，修改电话等使用该旧号码获取
    this->_phoneToChange = phone;

    // 4. 限定时间内（30s）禁止发送验证码，并显示倒计时
    this->_getVerifyCodeBtn->setEnabled(false);

    _leftTime     = 30;
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this,
            [=]()
            {
                if (_leftTime <= 1)
                {
                    // 倒计时结束
                    _getVerifyCodeBtn->setEnabled(true);
                    _getVerifyCodeBtn->setText("获取验证码");
                    timer->stop();
                    timer->deleteLater();
                    return;
                }
                _leftTime--;
                _getVerifyCodeBtn->setText(QString::number(_leftTime) + "s");
            });
    timer->start(1000);
}

void SelfInfoWidget::clickPhoneSubmitBtn()
{
    // 1. 先判定当前验证码是否已经收到
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    QString verifyCodeId          = dataCenter->getVerifyCodeId();
    if (verifyCodeId.isEmpty())
    {
        // 服务器还没有返回验证码响应
        Toast::showMessage("服务器尚未返回响应，稍后重试！");
        return;
    }
    // 若当前已经拿到 verifyCodeId，就清空 DataCenter 的数据，防止下次点击提交按钮时上一逻辑仍然有效
    dataCenter->resetVerifyCodeId("");

    // 2. 获取用户输入的验证码
    QString verifyCode = _verifyCodeEdit->text();
    if (verifyCode.isEmpty())
    {
        Toast::showMessage("验证码不能为空！");
        return;
    }
    _verifyCodeEdit->setText("");

    // 3. 发送请求，把当前验证码信息发送给服务器
    connect(dataCenter, &model::DataCenter::changePhoneDone, this, &SelfInfoWidget::clickPhoneSubmitBtnDone,
            Qt::UniqueConnection);
    dataCenter->changePhoneAsync(_phoneToChange, verifyCodeId, verifyCode);

    // 4. 让验证码按钮的倒计时时间停止
    _leftTime = 1;
}

void SelfInfoWidget::clickPhoneSubmitBtnDone()
{
    _layout->removeWidget(_verifyCodeTag);
    _layout->removeWidget(_verifyCodeEdit);
    _layout->removeWidget(_getVerifyCodeBtn);
    _layout->removeWidget(_phoneEdit);
    _layout->removeWidget(_phoneSubmitBtn);
    _verifyCodeTag->hide();
    _verifyCodeEdit->hide();
    _getVerifyCodeBtn->hide();
    _phoneEdit->hide();
    _phoneSubmitBtn->hide();

    _layout->addWidget(_phoneLabel, 3, 2);
    _phoneLabel->show();
    _phoneLabel->setText(_phoneToChange);
    _layout->addWidget(_phoneModifyBtn, 3, 3);
    _phoneModifyBtn->show();
}

void SelfInfoWidget::clickAvatarBtn()
{
    // 1. 弹出对话框，选择文件
    QString filter    = "Image Files (*.png,*.jpg,*.jpeg";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择头像", QDir::homePath(), filter);
    if (imagePath.isEmpty())
    {
        LOG() << "用户未选择任何头像";
        return;
    }

    // 2. 根据路径，读取到图片的内容
    QByteArray imageBytes = model::loadFileToByteArray(imagePath);

    // 3. 发送请求，修改头像
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::changeAvatarDone, this, &SelfInfoWidget::clickAvatarBtnDone,
            Qt::UniqueConnection);
    dataCenter->changeAvatarAsync(imageBytes);
}

void SelfInfoWidget::clickAvatarBtnDone()
{
    // 把设置的头像更新到界面上
    model::DataCenter *dataCenter = model::DataCenter::getInstance();
    _avatarBtn->setIcon(dataCenter->getMyself()->avatar);
}
